package register.utils;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;

/**
 * 图片验证码工具包
 */
public class PictureUtils {

    private int height;//验证码图片高度

    private int width;//验证码图片宽度

    private int num;//验证码上的字符个数

    public int getHeight() {
        return height;
    }
    public void setHeight(int height) {
        this.height = height;
    }
    public int getWidth() {
        return width;
    }
    public void setWidth(int width) {
        this.width = width;
    }
    public int getNum() {
        return num;
    }
    public void setNum(int num) {
        this.num = num;
    }
    public int getL_num() {
        return l_num;
    }
    public void setL_num(int l_num) {
        this.l_num = l_num;
    }


    private int l_num;//遮挡线条个数

    private BufferedImage bfImage;

    private Graphics g;//画笔

    Random rand = new Random();

    private char[] arrs;

    /**
     * @param height 验证码的高度
     * @param width 验证码的宽度
     * @param num 验证码所含随机字符数
     * @apiNote 默认遮挡线条为5条
     *
     * */
    public PictureUtils(int height,int width,int num,int l_num) {
        this.height = height;
        this.width = width;
        this.num = num;
        this.l_num = l_num;

        //初始化验证码信息
        initImage();

    }
    /**
     * @param height 验证码的高度
     * @param width 验证码的宽度
     * @param num 验证码所含随机字符数
     * @apiNote 默认遮挡线条为10条
     *
     * */
    public PictureUtils(int height,int width,int num) {
        this.height = height;
        this.width = width;
        this.num = num;

        //默认十条
        this.l_num = 10;

        //初始化验证码信息
        initImage();

    }


    /**
     *@apiNote 默认验证码高50，宽150，内容有四个随机字符,且遮挡线条为10
     *
     * */
    public PictureUtils() {
        this.height = 50;
        this.width = 120;
        this.num = 4;
        //默认十条
        this.l_num = 10;
        //初始化验证码信息
        initImage();
    }

    /**
     *初始化图片信息和画笔，并进行绘画
     **/
    private void initImage() {
        bfImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//创建一个图片
        g = bfImage.getGraphics();//获取画笔

        draw();//绘画
    }

    /**
     * 绘画
     * */
    private void draw() {
        //定义验证码字符集
        String  str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

        //红色、绿色和蓝色值的不透明的 sRGB 颜色，这些值都在 (0 - 255) 的范围内。
        int rBack;
        int gBack;
        int bBack;
        //动态生成验证码背景颜色
        rBack = rand.nextInt(255);
        gBack = rand.nextInt(255);
        bBack = rand.nextInt(255);

        //绘制图片背景
        this.g.setColor(new Color(rBack,gBack,bBack));
        this.g.fillRect(0, 0, width, height);

        arrs = new char[num];

        //获取num个字符
        for (int i = 0; i < arrs.length; i++) {
            int index = rand.nextInt(str.length());
            arrs[i] = str.charAt(index);
        }


        int r = 0;
        int g = 0;
        int b = 0;

        //绘制线条，作为涂鸦
        for (int i = 0; i < this.l_num; i++) {
            r = rand.nextInt(255);
            g = rand.nextInt(255);
            b = rand.nextInt(255);
            this.g.setColor(new Color(r,g,b));
            this.g.drawLine(rand.nextInt(width), rand.nextInt(height), rand.nextInt(width), rand.nextInt(height));
        }

        //绘制字符
        for (int i = 0; i < arrs.length; i++) {
            //动态生成验证码字符颜色
            //通过while额循环控制字符颜色不与背景颜色相同
            while(true) {
                r = rand.nextInt(255);
                g = rand.nextInt(255);
                b = rand.nextInt(255);
                if(r != rBack || g != gBack || b != bBack) {
                    break;
                }
            }
            //设置画笔颜色
            this.g.setColor(new Color(r,g,b));
            //设置画笔字体
            this.g.setFont(new Font("楷体", Font.BOLD, 25));
            //设置字符高度
            int h = 25;
            if(height > 25) {
                h = height / 2 + 10;
            }
            h = rand.nextInt(20) + h - 10 ;//控制每个字符高度在某个区间内随机生成

            int w = i * 25 + 5 * (i + 1);
            w = rand.nextInt(10) + w - 5;//控制每个字符宽度在某个区间内随机生成
            //绘制字符
            this.g.drawString(Character.toString(arrs[i]), w, h);
        }
    }

    /**
     * @return 返回验证码内容的字符串
     * */
    public String getCode() {

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < arrs.length; i++) {
            sb.append(arrs[i]);
        }
        return sb.toString();
    }

    /**
     * @return 返回已生成的验证码图片
     * */
    public BufferedImage getImage() {
        return bfImage;
    }


    /**
     * @apiNote 刷新验证码
     * */
    public void update() {
        initImage();
    }

}